array() returns something weird

array() returns something weird

am 22.08.2009 19:03:12 von webmaster

Hello!

I am almost certain I am hitting some kind of bug. All of a sudden, array()=
=20
stops returning an empty array and starts returning something weird. The we=
ird=20
thing behaves as NULL in most circumstances (e.g. gettype() says NULL),=20
except:

$foo=3Darray(); // <-- weird thing returned
$foo[]=3D"bar";

causes "Fatal error: [] operator not supported for strings", which is diffe=
rent=20
from the regular behavior of:

$foo=3Dnull;
$foo[]=3D"bar"; // <-- $foo simply becomes an array

The problem is not limited to one place in code, and indeed before the fata=
l=20
caused by append-assignment I get several warnings like "array_diff_key():=
=20
Argument #1 is not an array", where the offending argument receives a resul=
t of=20
array().

The effect is not random, i.e. it always breaks identically when the same=20
script processes the same data. However I was so far unable to create a=20
minimal test case that triggers the bug. My script is rather involved, and=
=20
here are some things it uses:

- Exceptions
- DOM to-fro SimpleXML
- lots of multi-level output buffering

Disabling Zend Optimizer doesn't help. Disabling Zend Memory Manager is=20
apparently impossible. Memory usage is below 10MB out of 128MB limit.

Any similar experiences? Ideas what to check for? Workarounds?

=46rom phpinfo():

PHP Version:
5.2.9 (can't easily upgrade - shared host)

System:
=46reeBSD 7.1-RELEASE-p4 FreeBSD 7.1-RELEASE-p4 #0: Wed Apr 15 15:48:43 UTC=
2009 =20
amd64

Configure Command:
'./configure' '--enable-bcmath' '--enable-calendar' '--enable-dbase' '--ena=
ble-
exif' '--enable-fastcgi' '--enable-force-cgi-redirect' '--enable-ftp' '--
enable-gd-native-ttf' '--enable-libxml' '--enable-magic-quotes' '--enable-
maintainer-zts' '--enable-mbstring' '--enable-pdo=3Dshared' '--enable-safe-=
mode'=20
'--enable-soap' '--enable-sockets' '--enable-ucd-snmp-hack' '--enable-wddx'=
=20
'--enable-zend-multibyte' '--enable-zip' '--prefix=3D/usr' '--with-bz2' '--=
with-
curl=3D/opt/curlssl/' '--with-curlwrappers' '--with-freetype-dir=3D/usr/loc=
al' '--
with-gd' '--with-gettext' '--with-imap=3D/opt/php_with_imap_client/' '--wit=
h-
imap-ssl=3D/usr/local' '--with-jpeg-dir=3D/usr/local' '--with-libexpat-
dir=3D/usr/local' '--with-libxml-dir=3D/opt/xml2' '--with-libxml-dir=3D/opt=
/xml2/'=20
'--with-mcrypt=3D/opt/libmcrypt/' '--with-mhash=3D/opt/mhash/' '--with-mime=
=2Dmagic'=20
'--with-mysql=3D/usr/local' '--with-mysql-sock=3D/tmp/mysql.sock' '--with-
mysqli=3D/usr/local/bin/mysql_config' '--with-openssl=3D/usr/local' '--with-
openssl-dir=3D/usr/local' '--with-pdo-mysql=3Dshared' '--with-pdo-sqlite=3D=
shared'=20
'--with-pgsql=3D/usr/local' '--with-pic' '--with-png-dir=3D/usr/local' '--w=
ith-
pspell' '--with-snmp' '--with-sqlite=3Dshared' '--with-tidy=3D/opt/tidy/' '=
=2D-with-
ttf' '--with-xmlrpc' '--with-xpm-dir=3D/usr/local' '--with-xsl=3D/opt/xslt/=
' '--
with-zlib' '--with-zlib-dir=3D/usr'

Thanks in advance,
Szczepan Holyszewski

--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Re: array() returns something weird

am 22.08.2009 20:39:06 von Lars Torben Wilson

2009/8/22 Szczepan Hołyszewski :
> Hello!
>
> I am almost certain I am hitting some kind of bug. All of a sudden, array=
()
> stops returning an empty array and starts returning something weird. The =
weird
> thing behaves as NULL in most circumstances (e.g. gettype() says NULL),
> except:
>
>        $foo=3Darray();      // <-- wei=
rd thing returned
>        $foo[]=3D"bar";
>
> causes "Fatal error: [] operator not supported for strings", which is dif=
ferent
> from the regular behavior of:

Hi there,

Without seeing the actual code, it's hard to say what the problem is.
However, I'd be pretty surprised if you've actually run into a bug in
PHP--I would first suspect a bug in your code. No offense
intended--that's just how it usually plays out. :)

What it looks like to me is that something is causing $foo to be a
string before the '$foo[] =3D "bar";' line is encountered. What do you
get if you put a gettype($foo); just before that line?

>        $foo=3Dnull;
>        $foo[]=3D"bar";      // <-- $fo=
o simply becomes an array
>
> The problem is not limited to one place in code, and indeed before the fa=
tal
> caused by append-assignment I get several warnings like "array_diff_key()=
:
> Argument #1 is not an array", where the offending argument receives a res=
ult of
> array().

This would appear to support my suspicion, but try inserting the
gettype($foo) (or better, var_export($foo);) just before one of the
lines which triggers the error, and post the results.

Can you post the code in a .zip file or online somewhere? If not,
that's cool, but it will probably make it harder to help you track it
down if you can't.


Regards,

Torben

> The effect is not random, i.e. it always breaks identically when the same
> script processes the same data. However I was so far unable to create a
> minimal test case that triggers the bug. My script is rather involved, an=
d
> here are some things it uses:
>
>  - Exceptions
>  - DOM to-fro SimpleXML
>  - lots of multi-level output buffering
>
> Disabling Zend Optimizer doesn't help. Disabling Zend Memory Manager is
> apparently impossible. Memory usage is below 10MB out of 128MB limit.
>
> Any similar experiences? Ideas what to check for? Workarounds?
>
> From phpinfo():
>
> PHP Version:
> 5.2.9 (can't easily upgrade - shared host)
>
> System:
> FreeBSD 7.1-RELEASE-p4 FreeBSD 7.1-RELEASE-p4 #0: Wed Apr 15 15:48:43 UTC=
2009
> amd64
>
> Configure Command:
> './configure' '--enable-bcmath' '--enable-calendar' '--enable-dbase' '--e=
nable-
> exif' '--enable-fastcgi' '--enable-force-cgi-redirect' '--enable-ftp' '--
> enable-gd-native-ttf' '--enable-libxml' '--enable-magic-quotes' '--enable=
-
> maintainer-zts' '--enable-mbstring' '--enable-pdo=3Dshared' '--enable-saf=
e-mode'
> '--enable-soap' '--enable-sockets' '--enable-ucd-snmp-hack' '--enable-wdd=
x'
> '--enable-zend-multibyte' '--enable-zip' '--prefix=3D/usr' '--with-bz2' '=
--with-
> curl=3D/opt/curlssl/' '--with-curlwrappers' '--with-freetype-dir=3D/usr/l=
ocal' '--
> with-gd' '--with-gettext' '--with-imap=3D/opt/php_with_imap_client/' '--w=
ith-
> imap-ssl=3D/usr/local' '--with-jpeg-dir=3D/usr/local' '--with-libexpat-
> dir=3D/usr/local' '--with-libxml-dir=3D/opt/xml2' '--with-libxml-dir=3D/o=
pt/xml2/'
> '--with-mcrypt=3D/opt/libmcrypt/' '--with-mhash=3D/opt/mhash/' '--with-mi=
me-magic'
> '--with-mysql=3D/usr/local' '--with-mysql-sock=3D/tmp/mysql.sock' '--with=
-
> mysqli=3D/usr/local/bin/mysql_config' '--with-openssl=3D/usr/local' '--wi=
th-
> openssl-dir=3D/usr/local' '--with-pdo-mysql=3Dshared' '--with-pdo-sqlite=
=3Dshared'
> '--with-pgsql=3D/usr/local' '--with-pic' '--with-png-dir=3D/usr/local' '-=
-with-
> pspell' '--with-snmp' '--with-sqlite=3Dshared' '--with-tidy=3D/opt/tidy/'=
'--with-
> ttf' '--with-xmlrpc' '--with-xpm-dir=3D/usr/local' '--with-xsl=3D/opt/xsl=
t/' '--
> with-zlib' '--with-zlib-dir=3D/usr'
>
> Thanks in advance,
> Szczepan Holyszewski
>
> --
> PHP General Mailing List (http://www.php.net/)
> To unsubscribe, visit: http://www.php.net/unsub.php
>
>

--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Re: array() returns something weird

am 22.08.2009 21:52:55 von webmaster

> What it looks like to me is that something is causing $foo to be a
> string before the '$foo[] = "bar";' line is encountered. What do you
> get if you put a gettype($foo); just before that line?
>
> > $foo=null;
> > $foo[]="bar"; // <-- $foo simply becomes an array

NULL. That is the problem. I _did_ put a gettype($foo) before the actual line.

OK, here are exact four lines of my code:

$ret=array();
foreach(self::$_allowed as $r => $a)
if ($a)
$ret[]=$r;

As you can see, there is not a shred of a chance for $ret to become something
other than empty array between initialization and the last line in the above
snippet which causes the fatal errror. There's no __staticGet in 5.2.9, so
self::$_allowed cannot have side effects.

Secondly, the above code starts failing after it has executed successfully
dozens of times (and yes, the last line _does_ get executed; in fact self::
$_allowed contains configuration information that doesn't change at runtime).

Thirdly...

> > The problem is not limited to one place in code, and indeed before the
> > fatal caused by append-assignment I get several warnings like
> > "array_diff_key(): Argument #1 is not an array", where the offending
> > argument receives a result of array().
>
> This would appear to support my suspicion, but try inserting the
> gettype($foo) (or better, var_export($foo);) just before one of the
> lines which triggers the error, and post the results.

No, I don't think it supports your suspicion. Conversely, it indicates that
once array() returns a strangelet, it starts returning strangelets all over
the place. Initially it only triggers warnings but eventually one of the
returned strangelets is used in a way that triggers a fatal error.

As per your request:

//at the beginning of the script:

$GLOBALS['offending_line_execution_count']=0;

// /srv/home/[munged]/public_html/scripts/common.php line 161 and on
// instrumented as per your request:

public static function GetAllowed() {

if (debug_mode()) echo ++$GLOBALS['offending_line_execution_count']."
";
$ret=array();
if (debug_mode()) echo var_export($ret)."
";
foreach(self::$_allowed as $r => $a)
if ($a)
$ret[]=$r;

if (self::$_allowEmpty) $ret[]="";
return $ret;
}

Output tail:
-----------------------------------------------
28
array ( )
29
array ( )
30
array ( )
31
array ( )
32
array ( )

Warning: array_diff_key() [function.array-diff-key]: Argument #1 is not an array
in /srv/home/u80959ue/public_html/v3/scripts/SimpliciText.php on line 350

Warning: Invalid argument supplied for foreach() in
/srv/home/u80959ue/public_html/v3/scripts/SimpliciText.php on line 351

Warning: array_merge() [function.array-merge]: Argument #2 is not an array in
/srv/home/u80959ue/public_html/v3/scripts/SimpliciText.php on line 357

Warning: Invalid argument supplied for foreach() in
/srv/home/u80959ue/public_html/scripts/common.php on line 28

Warning: Invalid argument supplied for foreach() in
/srv/home/u80959ue/public_html/scripts/common.php on line 28

Warning: Invalid argument supplied for foreach() in
/srv/home/u80959ue/public_html/scripts/common.php on line 28
33
NULL

Fatal error: [] operator not supported for strings in
/srv/home/u80959ue/public_html/scripts/common.php on line 168
--------------------------------------------------

The warnings come from other uses of array().

But wait! There is this invocation of debug_mode() between initialization of
$ret var_export. Let's factor it out to be safe:

$debugmode=debug_mode();
if ($debugmode) echo ++$GLOBALS['offending_line_execution_count']."
";
$ret=array();
if ($debugmode) echo var_export($ret)."
";

And now the output ends with:

------------------------------------
Warning: Invalid argument supplied for foreach() in
/srv/home/u80959ue/public_html/scripts/common.php on line 28
33

Fatal error: [] operator not supported for strings in
/srv/home/u80959ue/public_html/scripts/common.php on line 169
------------------------------------

No NULL after 33? What the heck is going on? Does array() now return something
that var_exports to an empty string, or does it destroy local variables? Let's
see:

if ($debugmode) echo var_export($ret)."
"; else echo "WTF?!?!?
";

And the output:
------------------------------------
Warning: Invalid argument supplied for foreach() in
/srv/home/u80959ue/public_html/scripts/common.php on line 28
33
WTF?!?!?

Fatal error: [] operator not supported for strings in
/srv/home/u80959ue/public_html/scripts/common.php on line 169
---------------------------------------

Indeed, the use of array(), once it starts misbehaving, wreaks havoc in the
local scope (possibly including the variable to which its result is assigned).

> Can you post the code in a .zip file or online somewhere?

Unfortunately not.

Szczepan Holyszewski

--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Re: array() returns something weird

am 22.08.2009 23:08:10 von Lars Torben Wilson

2009/8/22 Szczepan Hołyszewski :
>> What it looks like to me is that something is causing $foo to be a
>> string before the '$foo[] =3D "bar";' line is encountered. What do you
>> get if you put a gettype($foo); just before that line?
>>
>> >        $foo=3Dnull;
>> >        $foo[]=3D"bar";      // <-- =
$foo simply becomes an array
>
> NULL. That is the problem. I _did_ put a gettype($foo) before the actual =
line.
>
> OK, here are exact four lines of my code:
>
>        $ret=3Darray();
>        foreach(self::$_allowed as $r =3D> $a)
>                if ($a)
>                     =C2=
=A0  $ret[]=3D$r;
>
> As you can see, there is not a shred of a chance for $ret to become somet=
hing
> other than empty array between initialization and the last line in the ab=
ove
> snippet which causes the fatal errror. There's no __staticGet in 5.2.9, s=
o
> self::$_allowed cannot have side effects.
>
> Secondly, the above code starts failing after it has executed successfull=
y
> dozens of times (and yes, the last line _does_ get executed; in fact self=
::
> $_allowed contains configuration information that doesn't change at runti=
me).
>
> Thirdly...
>
>> > The problem is not limited to one place in code, and indeed before the
>> > fatal caused by append-assignment I get several warnings like
>> > "array_diff_key(): Argument #1 is not an array", where the offending
>> > argument receives a result of array().
>>
>> This would appear to support my suspicion, but try inserting the
>> gettype($foo) (or better, var_export($foo);) just before one of the
>> lines which triggers the error, and post the results.
>
> No, I don't think it supports your suspicion. Conversely, it indicates th=
at
> once array() returns a strangelet, it starts returning strangelets all ov=
er
> the place. Initially it only triggers warnings but eventually one of the
> returned strangelets is used in a way that triggers a fatal error.
>
> As per your request:
>
>        //at the beginning of the script:
>
>        $GLOBALS['offending_line_execution_count']=3D0=
;
>
>        // /srv/home/[munged]/public_html/scripts/comm=
on.php line 161 and on
>        // instrumented as per your request:
>
>        public static function GetAllowed() {
>
>                if (debug_mode()) =
echo ++$GLOBALS['offending_line_execution_count']."
";
>                $ret=3Darray();
>                if (debug_mode()) =
echo var_export($ret)."
";
>                foreach(self::$_al=
lowed as $r =3D> $a)
>                     =C2=
=A0  if ($a)
>                     =C2=
=A0          $ret[]=3D$r;
>
>                if (self::$_allowE=
mpty) $ret[]=3D"";
>                return $ret;
>        }
>
> Output tail:
> -----------------------------------------------
> 28
> array ( )
> 29
> array ( )
> 30
> array ( )
> 31
> array ( )
> 32
> array ( )
>
> Warning: array_diff_key() [function.array-diff-key]: Argument #1 is not a=
n array
> in /srv/home/u80959ue/public_html/v3/scripts/SimpliciText.php on line 350
>
> Warning: Invalid argument supplied for foreach() in
> /srv/home/u80959ue/public_html/v3/scripts/SimpliciText.php on line 351
>
> Warning: array_merge() [function.array-merge]: Argument #2 is not an arra=
y in
> /srv/home/u80959ue/public_html/v3/scripts/SimpliciText.php on line 357
>
> Warning: Invalid argument supplied for foreach() in
> /srv/home/u80959ue/public_html/scripts/common.php on line 28
>
> Warning: Invalid argument supplied for foreach() in
> /srv/home/u80959ue/public_html/scripts/common.php on line 28
>
> Warning: Invalid argument supplied for foreach() in
> /srv/home/u80959ue/public_html/scripts/common.php on line 28
> 33
> NULL
>
> Fatal error: [] operator not supported for strings in
> /srv/home/u80959ue/public_html/scripts/common.php on line 168
> --------------------------------------------------
>
> The warnings come from other uses of array().
>
> But wait! There is this invocation of debug_mode() between initialization=
of
> $ret var_export. Let's factor it out to be safe:
>
>                $debugmode=3Ddebug=
_mode();
>                if ($debugmode) ec=
ho ++$GLOBALS['offending_line_execution_count']."
";
>                $ret=3Darray();
>                if ($debugmode) ec=
ho var_export($ret)."
";
>
> And now the output ends with:
>
> ------------------------------------
> Warning: Invalid argument supplied for foreach() in
> /srv/home/u80959ue/public_html/scripts/common.php on line 28
> 33
>
> Fatal error: [] operator not supported for strings in
> /srv/home/u80959ue/public_html/scripts/common.php on line 169
> ------------------------------------
>
> No NULL after 33? What the heck is going on? Does array() now return some=
thing
> that var_exports to an empty string, or does it destroy local variables? =
Let's
> see:
>
>                if ($debugmode) ec=
ho var_export($ret)."
"; else echo "WTF?!?!?
";
>
> And the output:
> ------------------------------------
> Warning: Invalid argument supplied for foreach() in
> /srv/home/u80959ue/public_html/scripts/common.php on line 28
> 33
> WTF?!?!?
>
> Fatal error: [] operator not supported for strings in
> /srv/home/u80959ue/public_html/scripts/common.php on line 169
> ---------------------------------------
>
> Indeed, the use of array(), once it starts misbehaving, wreaks havoc in t=
he
> local scope (possibly including the variable to which its result is assig=
ned).
>
>> Can you post the code in a .zip file or online somewhere?
>
> Unfortunately not.
>
> Szczepan Holyszewski

Hm. . .it does look odd. Searching the bugs database at
http://bugs.php.net does turn up one other report (at
http://bugs.php.net/bug.php?id=3D47870 ) of array() returning NULL in
certain hard-to-duplicate circumstances on FreeBSD, although it's a
different version of FreeBSD and is reported against
5.3CVS-2009-04-01. There are differences but the similarities are
suspicious. That particular bug was fixed but if this does in fact
turn out to be a bug in PHP then the ability to test other versions
would be very useful. Too bad about the shared host. I know how hard
it can be to get them to install other versions, even if just for
testing.

I don't suppose you have a development environment on another machine
where you can test another version of PHP? If not, it's going to be
slightly difficult to pin down.

It may be worth it for you to add a comment to the above bug report.
The current 5.2 is only at 5.2.10 so the version you're using isn't
very old, and a fix for this problem is not specifically mentioned in
the PHP 5.2.10 changelog.


Good luck!

Torben

--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Re: array() returns something weird

am 22.08.2009 23:48:50 von Ralph Deffke

well, when I saw ur post I got immediately the thought I would bed it has to
do with some stuff of $this or self.

I did play arround a bit with class creation the last days and yes, with
using self parent and $this I did put the HTTPPD in unstable and sometimes
it died without beeing able to send any error.

well this doesn't help very mutch.

I have two point:

(1)ur code is ( sorry ) lazy written, invest the brackets !! ur code writing
is predestinated for that type of error. shooting variable types arround by
pulling out of foreach loops, if's, .... is typical.

(2) using static variables are known for type missmatch errors just anything
has acces to them even if the containing class is not instantinated. many
dirty things can happen unless of corse they are not private.

further sugestions: check if you work on ur arrays with functions returning
array on success but false on fail or something like that. also a typical
source for that type of error

are u using magic __set ? I ran into a type change as well with it

good luck

ralph_deffke@yahoo.de


"Szczepan Holyszewski" wrote in message
news:200908222152.55846.webmaster@strefarytmu.pl...
> > What it looks like to me is that something is causing $foo to be a
> > string before the '$foo[] = "bar";' line is encountered. What do you
> > get if you put a gettype($foo); just before that line?
> >
> > > $foo=null;
> > > $foo[]="bar"; // <-- $foo simply becomes an array
>
> NULL. That is the problem. I _did_ put a gettype($foo) before the actual
line.
>
> OK, here are exact four lines of my code:
>
> $ret=array();
> foreach(self::$_allowed as $r => $a)
> if ($a)
> $ret[]=$r;
>
> As you can see, there is not a shred of a chance for $ret to become
something
> other than empty array between initialization and the last line in the
above
> snippet which causes the fatal errror. There's no __staticGet in 5.2.9, so
> self::$_allowed cannot have side effects.
>
> Secondly, the above code starts failing after it has executed successfully
> dozens of times (and yes, the last line _does_ get executed; in fact
self::
> $_allowed contains configuration information that doesn't change at
runtime).
>
> Thirdly...
>
> > > The problem is not limited to one place in code, and indeed before the
> > > fatal caused by append-assignment I get several warnings like
> > > "array_diff_key(): Argument #1 is not an array", where the offending
> > > argument receives a result of array().
> >
> > This would appear to support my suspicion, but try inserting the
> > gettype($foo) (or better, var_export($foo);) just before one of the
> > lines which triggers the error, and post the results.
>
> No, I don't think it supports your suspicion. Conversely, it indicates
that
> once array() returns a strangelet, it starts returning strangelets all
over
> the place. Initially it only triggers warnings but eventually one of the
> returned strangelets is used in a way that triggers a fatal error.
>
> As per your request:
>
> //at the beginning of the script:
>
> $GLOBALS['offending_line_execution_count']=0;
>
> // /srv/home/[munged]/public_html/scripts/common.php line 161 and on
> // instrumented as per your request:
>
> public static function GetAllowed() {
>
> if (debug_mode()) echo
++$GLOBALS['offending_line_execution_count']."
";
> $ret=array();
> if (debug_mode()) echo var_export($ret)."
";
> foreach(self::$_allowed as $r => $a)
> if ($a)
> $ret[]=$r;
>
> if (self::$_allowEmpty) $ret[]="";
> return $ret;
> }
>
> Output tail:
> -----------------------------------------------
> 28
> array ( )
> 29
> array ( )
> 30
> array ( )
> 31
> array ( )
> 32
> array ( )
>
> Warning: array_diff_key() [function.array-diff-key]: Argument #1 is not an
array
> in /srv/home/u80959ue/public_html/v3/scripts/SimpliciText.php on line 350
>
> Warning: Invalid argument supplied for foreach() in
> /srv/home/u80959ue/public_html/v3/scripts/SimpliciText.php on line 351
>
> Warning: array_merge() [function.array-merge]: Argument #2 is not an array
in
> /srv/home/u80959ue/public_html/v3/scripts/SimpliciText.php on line 357
>
> Warning: Invalid argument supplied for foreach() in
> /srv/home/u80959ue/public_html/scripts/common.php on line 28
>
> Warning: Invalid argument supplied for foreach() in
> /srv/home/u80959ue/public_html/scripts/common.php on line 28
>
> Warning: Invalid argument supplied for foreach() in
> /srv/home/u80959ue/public_html/scripts/common.php on line 28
> 33
> NULL
>
> Fatal error: [] operator not supported for strings in
> /srv/home/u80959ue/public_html/scripts/common.php on line 168
> --------------------------------------------------
>
> The warnings come from other uses of array().
>
> But wait! There is this invocation of debug_mode() between initialization
of
> $ret var_export. Let's factor it out to be safe:
>
> $debugmode=debug_mode();
> if ($debugmode) echo ++$GLOBALS['offending_line_execution_count']."
";
> $ret=array();
> if ($debugmode) echo var_export($ret)."
";
>
> And now the output ends with:
>
> ------------------------------------
> Warning: Invalid argument supplied for foreach() in
> /srv/home/u80959ue/public_html/scripts/common.php on line 28
> 33
>
> Fatal error: [] operator not supported for strings in
> /srv/home/u80959ue/public_html/scripts/common.php on line 169
> ------------------------------------
>
> No NULL after 33? What the heck is going on? Does array() now return
something
> that var_exports to an empty string, or does it destroy local variables?
Let's
> see:
>
> if ($debugmode) echo var_export($ret)."
"; else echo "WTF?!?!?
";
>
> And the output:
> ------------------------------------
> Warning: Invalid argument supplied for foreach() in
> /srv/home/u80959ue/public_html/scripts/common.php on line 28
> 33
> WTF?!?!?
>
> Fatal error: [] operator not supported for strings in
> /srv/home/u80959ue/public_html/scripts/common.php on line 169
> ---------------------------------------
>
> Indeed, the use of array(), once it starts misbehaving, wreaks havoc in
the
> local scope (possibly including the variable to which its result is
assigned).
>
> > Can you post the code in a .zip file or online somewhere?
>
> Unfortunately not.
>
> Szczepan Holyszewski



--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Re: array() returns something weird

am 23.08.2009 00:34:06 von webmaster

> Hm. . .it does look odd. Searching the bugs database at
> http://bugs.php.net does turn up one other report (at
> http://bugs.php.net/bug.php?id=47870 ) of array() returning NULL in
> certain hard-to-duplicate circumstances on FreeBSD,

Yes, I found it even before posting here, but I wasn't sure whether to file a
new report or comment under this one. If your intuition is that these bugs are
related, then I will do the latter. Thank you for your attention.

> I don't suppose you have a development environment on another
> machine where you can test another version of PHP?

Assuming you mean a FreeBSD environment, nope :( but I will try on Linux
tomorrow.

Regards,
Szczepan Holyszewski


--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Re: array() returns something weird

am 23.08.2009 01:14:32 von Lars Torben Wilson

2009/8/22 Szczepan Hołyszewski :
>> Hm. . .it does look odd. Searching the bugs database at
>> http://bugs.php.net does turn up one other report (at
>> http://bugs.php.net/bug.php?id=3D47870 ) of array() returning NULL in
>> certain hard-to-duplicate circumstances on FreeBSD,
>
> Yes, I found it even before posting here, but I wasn't sure whether to fi=
le a
> new report or comment under this one. If your intuition is that these bug=
s are
> related, then I will do the latter. Thank you for your attention.

Well, the only things I'm basing my suspicion on are the nature of the
problem, the OS similarity and the fact that it seems to be difficult
to reproduce the problem reliably. The major problem with this guess
is that the original bug report does state that the bug did not show
up under 5.2.

>> I don't suppose you have a development environment on another
>> machine where you can test another version of PHP?
>
> Assuming you mean a FreeBSD environment, nope :( but I will try on Linux
> tomorrow.

OK. I do think (as I'm sure you know) that the best test would be in a
matching environment (since the result was reported to be different
under Linux for that bug), but of course that's not always realistic.

> Regards,
> Szczepan Holyszewski

I hope your problem can be resolved. If it does turn out to be a bug
in PHP I hope that will be enough to convince your host to upgrade.


Regards,

Torben

--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

DOMNode children iteration (was Re: array() returns something weird)

am 25.08.2009 01:22:24 von webmaster

--Boundary-00=_wCykKKQfRHGvvUX
Content-Type: Text/Plain;
charset="utf-8"
Content-Transfer-Encoding: quoted-printable


Hi Lars and list!

New facts about the strange bug initially diagnosed as array() returning NU=
LL:

=46irstly, the issue is not really about array() returning null, but about =
full=20
blown UndefinedBehavior(TM) progressively trashing local variables. It just=
so=20
happened that I noticed it first with a variable to which array() had been=
=20
assigned just before things began breaking.

Secondly, I proudly present the culprit: things break when I iterate over a=
=20
DOMNode's children *by reference* using firstChild and nextSibling:

for($child=3D&$node->firstChild; $child; $child=3D&$child->nextSibling) {

//processing...
}

No problems if iteration is done by value or by DOMNodeList (childNodes,=20
DOMXPath...).

HOWEVER,

I still consider this a bug because it destablizes PHP. After the evil loop=
=20
has finished, things happen that should never happen, like a variable being=
=20
NULL immediately after being assigned array().

I attach a demonstration. It is a self-contained commented script that you =
can=20
execute from command line. Also attached is output on my machine.

Best regards,
Szczepan Hołyszewski

--Boundary-00=_wCykKKQfRHGvvUX
Content-Type: application/x-php;
name="testme.php"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename="testme.php"


/*
This program demonstrates mayhem caused by iterating over a DOMNode's children
using firstChild and nextSibling TAKEN BY REFERENCE.

It instantiates a DOMDocument, loads an XML fragment into it and processes it
three times - the good way, the mixed way (read below) and the evil way. Each time
recursion progress is logged and (trivial) transformation result is dumped
(if not errored out earlier).

* First time it takes a path in renderObject() that iterates over
child nodes using a DOMNodeList obtained with a DOMXPath query.

* Second time it uses DOMNodeList at the outermost level in renderObject()
but firstChild/nextSibling by reference at inner levels. This
demonstrates very nice trashing of local variables from which
transformation result is assembled in renderObject().

* Third time it always uses firstChild/nextSibling in renderObject().
On my machine it errors out at the outermost level but AFTER returning
from recursion.
*/


define('GOOD_WAY', true);
define('EVIL_WAY', false);

//The XML is formatted so that objects only contain params
//and no text or whitespace in between
$xmlfragment = <<
Some text.

Some parameter text.
Some parameter text.

Some nested parameter text.
Some nested parameter text.

true

More nested parameter text
More nested parameter text


Some more text

XMLFRAGMENT;

$doc = new DOMDocument("1.0", "utf-8"); $doc->loadXML($xmlfragment);

$root = $doc->childNodes->item(0);

//uncomment to display errors
//ini_set("display_errors", "On");

echo "THE GOOD WAY (DOMNodeList):\n\n";
echo "Recursion structure:\n\n";
$innerWay = GOOD_WAY;
$result=render($root, true);
echo "\nTransformation result:\n$result\n";
echo "Success!\n\n";

echo "THE MIXED WAY (DOMNodeList at outermost level, then firstChild/nextSibling by ref):\n\n";
echo "Recursion structure:\n\n";
$innerWay = EVIL_WAY;
$result=render($root, true);
echo "\nTransformation result:\n$result\n";
echo "Is it really a success?\n\n";

echo "THE EVIL WAY (firstChild/nextSibling by ref):\n\n";
echo "Recursion structure:\n\n";
$result=render($root, false);
echo "\nTransformation result:\n$result\n";
echo "Unexpected success!\n\n";

function render(&$node, $whichWay) {

$ret="";
//for each node
for($i=0; $i<$node->childNodes->length; ++$i) {

$child = $node->childNodes->item($i);

//if text node, append
if ($child instanceof DOMText) $ret .= $child->wholeText;

//if , render and append
else if ($child instanceof DOMElement && $child->tagName == "object")

$ret .= renderObject($child, $whichWay);
}
return $ret;
}

function renderObject(&$node, $whichWay) {

$objectName = $node->getAttribute("name");
$objectType = $node->getAttribute("type");
$params = array();

if ($whichWay==GOOD_WAY) {

$xpath = new DOMXPath($node->ownerDocument);
$paramNodes = $xpath->evaluate("./param", $node);
for($i=0; $i<$paramNodes->length; ++$i) {

$paramNode = $paramNodes->item($i);
$paramName = $paramNode->getAttribute("name");
echo "->render()\n";
$paramValue = render($paramNode, $GLOBALS['innerWay']); //which way to use at inner levels?
echo "<-\n";
$params[$paramName] = $paramValue;
}
}

else { //($which_way == EVIL_WAY)

for($paramNode = &$node->firstChild; $paramNode; $paramNode = &$paramNode->nextSibling) {

$paramName = $paramNode->getAttribute("name");
echo "->render()\n";
$paramValue = render($paramNode, false);
echo "<-\n";
$params[$paramName]=$paramValue;
}
}

//build some simple transformation result
$ret = "[object type='$objectType' name='$objectName']";
foreach($params as $n => $v) $ret.="[param name='$n']{$v}[/param]";
$ret.="[/object]";
return $ret;
}


--Boundary-00=_wCykKKQfRHGvvUX
Content-Type: text/plain;
charset="UTF-8";
name="output.txt"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename="output.txt"

THE GOOD WAY (DOMNodeList):

Recursion structure:

->render()
->render()
->render()
<-
->render()
<-
<-
<-

Transformation result:

Some text.
[object type='foo' name='bar'][param name='__default_content']
Some parameter text.
Some parameter text.
[object type='bar' name='nested'][param name='__default_content']
Some nested parameter text.
Some nested parameter text.
[object type='baz' name='deeply_nested'][param name='__default_content']
[/param][param name='bold']true[/param][/object]
More nested parameter text
More nested parameter text
[/param][/object]
[/param][/object]
Some more text

Success!

THE MIXED WAY (DOMNodeList at outermost level, then firstChild/nextSibling by ref):

Recursion structure:

->render()
->render()
->render()
<-
->render()
<-
<-
<-

Transformation result:

Some text.
[object type='foo' name='bar'][param name='__default_content']
Some parameter text.
Some parameter text.
__default_content[param name='__default_content']__default_content[/param][/object]
[/param][/object]
Some more text

Is it really a success?

THE EVIL WAY (firstChild/nextSibling by ref):

Recursion structure:

->render()
->render()
->render()
<-
->render()
<-


--Boundary-00=_wCykKKQfRHGvvUX
Content-Type: text/plain; charset=us-ascii

--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php
--Boundary-00=_wCykKKQfRHGvvUX--

DOMNode children iteration (was Re: array() returns something

am 25.08.2009 23:25:06 von Martin Scotta

--0016e6460856e412430471fdf7e1
Content-Type: multipart/alternative; boundary=0016e6460856e412350471fdf7df

--0016e6460856e412350471fdf7df
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

---------- Forwarded message ----------
From: Martin Scotta
Date: Tue, Aug 25, 2009 at 6:24 PM
Subject: Re: [PHP] DOMNode children iteration (was Re: array() returns
something weird)
To: webmaster@strefarytmu.pl


Fatal error: Call to a member function getAttribute() on a non-object in
testme.php on line *121*

I'm using a Apache/2.2.3 (Win32) PHP/5.2.6
Is the script correctly? I have removed the "&" in the loop and the script
returns the attached file.

It looks like a bogus bug?

2009/8/24 Szczepan Hołyszewski

>
> Hi Lars and list!
>
> New facts about the strange bug initially diagnosed as array() returning
> NULL:
>
> Firstly, the issue is not really about array() returning null, but about
> full
> blown UndefinedBehavior(TM) progressively trashing local variables. It ju=
st
> so
> happened that I noticed it first with a variable to which array() had bee=
n
> assigned just before things began breaking.
>
> Secondly, I proudly present the culprit: things break when I iterate over=
a
> DOMNode's children *by reference* using firstChild and nextSibling:
>
> for($child=3D&$node->firstChild; $child; $child=3D&$child->nextSib=
ling)
> {
>
> //processing...
> }
>
> No problems if iteration is done by value or by DOMNodeList (childNodes,
> DOMXPath...).
>
> HOWEVER,
>
> I still consider this a bug because it destablizes PHP. After the evil lo=
op
> has finished, things happen that should never happen, like a variable bei=
ng
> NULL immediately after being assigned array().
>
> I attach a demonstration. It is a self-contained commented script that yo=
u
> can
> execute from command line. Also attached is output on my machine.
>
> Best regards,
> Szczepan Hołyszewski
>
> --
> PHP General Mailing List (http://www.php.net/)
> To unsubscribe, visit: http://www.php.net/unsub.php
>



--=20
Martin Scotta



--=20
Martin Scotta

--0016e6460856e412350471fdf7df
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable



---------- Forwarded message ----------<=
br>From: Martin Scotta =
<>=
;


Date: Tue, Aug 25, 2009 at 6:24 PM
Subject: Re: [PHP] DOMNode children i=
teration (was Re: array() returns something weird)
To: webmaster@strefar=
ytmu.pl


Fatal error: Call to a member function =
getAttribute() on
a non-object in testme.php
on line 121


I'm using a Apache/2.2.3 (Win32) PHP/5=
..2.6
Is the script correctly? I have removed the "&" in th=
e loop and the script returns the attached file.

It looks like a bog=
us bug?



2009/8/24 Szczepan Hołyszewski ir=3D"ltr"><webmaster@strefarytmu.pl>
gmail_quote" style=3D"border-left: 1px solid rgb(204, 204, 204); margin: 0p=
t 0pt 0pt 0.8ex; padding-left: 1ex;">



Hi Lars and list!



New facts about the strange bug initially diagnosed as array() returning NU=
LL:



Firstly, the issue is not really about array() returning null, but about fu=
ll

blown UndefinedBehavior(TM) progressively trashing local variables. It just=
so

happened that I noticed it first with a variable to which array() had been<=
br>
assigned just before things began breaking.



Secondly, I proudly present the culprit: things break when I iterate over a=


DOMNode's children *by reference* using firstChild and nextSibling:



       for($child=3D&$node->firstChild; $child;=
$child=3D&$child->nextSibling) {



               //processing...

       }



No problems if iteration is done by value or by DOMNodeList (childNodes, >
DOMXPath...).



HOWEVER,



I still consider this a bug because it destablizes PHP. After the evil loop=


has finished, things happen that should never happen, like a variable being=


NULL immediately after being assigned array().



I attach a demonstration. It is a self-contained commented script that you =
can

execute from command line. Also attached is output on my machine.



Best regards,

Szczepan Hołyszewski


--

PHP General Mailing List ( >http://www.php.net/)

To unsubscribe, visit: blank">http://www.php.net/unsub.php


=3D"all">
--
Martin Scotta




--
Martin Scotta


--0016e6460856e412350471fdf7df--

--0016e6460856e412430471fdf7e1
Content-Type: text/plain; charset=us-ascii

--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php
--0016e6460856e412430471fdf7e1--

Re: DOMNode children iteration (was Re: array() returns something weird)

am 26.08.2009 09:47:49 von webmaster

Martin Scotta wrote:

> Fatal error: Call to a member function getAttribute() on a non-object in
> testme.php on line *121*

Yes, this is _how_ the unmodified script errors out. It is not shown in the=
=20
output I attached in my previous message because display_errors is Off in m=
y=20
php.ini, and the line that sets it to On in my script is commented out.

> I'm using a Apache/2.2.3 (Win32) PHP/5.2.6

I am not using Apache at all. The same error can be seen when I run the scr=
ipt=20
directly through php on the command line.

> Is the script correctly? I have removed the "&" in the loop

I know that iterating a DOMNode's children using firstChild and nextSibling=
by=20
reference causes trouble, thank you. The problem is that it causes trouble=
=20
with objects unrelated to the loop itself, e.g. to variables defined _after=
_=20
the loop has terminated.

> and the script returns the attached file.

Do you mean it returns what is in the output file _I_ have attached, or did=
=20
_you_ try to attach something? If that is the case, then your attachment=20
didn't get through.

> It looks like a bogus bug?

I am certain it _is_ a genuine bug. For example, in PHP when you write:

$foo =3D array();
echo gettype($foo);

the output should not be NULL, but in my example script (unmodified, with=20
iteration by reference) things like this start happening at some point.

Regards,
Szczepan Hołyszewski

--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

RE: DOMNode children iteration (was Re: array() returns something weird)

am 26.08.2009 10:50:10 von M.Ford

PiAtLS0tLU9yaWdpbmFsIE1lc3NhZ2UtLS0tLQ0KPiBGcm9tOiBTemN6ZXBh
biBIb8WCeXN6ZXdza2kgW21haWx0bzp3ZWJtYXN0ZXJAc3RyZWZhcnl0bXUu
cGxdDQo+IFNlbnQ6IDI2IEF1Z3VzdCAyMDA5IDA4OjQ4DQo+IA0KPiBNYXJ0
aW4gU2NvdHRhIHdyb3RlOg0KPiANCj4gPiBGYXRhbCBlcnJvcjogQ2FsbCB0
byBhIG1lbWJlciBmdW5jdGlvbiBnZXRBdHRyaWJ1dGUoKSBvbiBhIG5vbi0N
Cj4gb2JqZWN0IGluDQo+ID4gdGVzdG1lLnBocCBvbiBsaW5lICoxMjEqDQo+
IA0KPiBZZXMsIHRoaXMgaXMgX2hvd18gdGhlIHVubW9kaWZpZWQgc2NyaXB0
IGVycm9ycyBvdXQuIEl0IGlzIG5vdCBzaG93bg0KPiBpbiB0aGUNCj4gb3V0
cHV0IEkgYXR0YWNoZWQgaW4gbXkgcHJldmlvdXMgbWVzc2FnZSBiZWNhdXNl
IGRpc3BsYXlfZXJyb3JzIGlzDQo+IE9mZiBpbiBteQ0KPiBwaHAuaW5pLCBh
bmQgdGhlIGxpbmUgdGhhdCBzZXRzIGl0IHRvIE9uIGluIG15IHNjcmlwdCBp
cyBjb21tZW50ZWQNCj4gb3V0Lg0KPiANCj4gPiBJJ20gdXNpbmcgYSBBcGFj
aGUvMi4yLjMgKFdpbjMyKSBQSFAvNS4yLjYNCj4gDQo+IEkgYW0gbm90IHVz
aW5nIEFwYWNoZSBhdCBhbGwuIFRoZSBzYW1lIGVycm9yIGNhbiBiZSBzZWVu
IHdoZW4gSSBydW4NCj4gdGhlIHNjcmlwdA0KPiBkaXJlY3RseSB0aHJvdWdo
IHBocCBvbiB0aGUgY29tbWFuZCBsaW5lLg0KPiANCj4gPiBJcyB0aGUgc2Ny
aXB0IGNvcnJlY3RseT8gSSBoYXZlIHJlbW92ZWQgdGhlICImIiBpbiB0aGUg
bG9vcA0KDQpJIHJlYWxseSBjYW4ndCBzZWUgd2h5IHlvdSdkIHdhbnQgdG8g
dXNlIHJlZmVyZW5jZXMgaW4gdGhlIHBvc3RlZCBsb29wIGFueXdheSAtLSBp
dCdzIG5vdCBsaWtlbHkgdG8gZ2FpbiB5b3UgYW55IHBlcmZvcm1hbmNlLCBh
bmQsIGFzIEkgdW5kZXJzdGFuZCBpdCwgbWF5IGFjdHVhbGx5IHJ1biBtb3Jl
IHNsb3dseSB0aGFuIHRoZSBub24tcmVmZXJlbmNlIHZlcnNpb24uDQogDQo+
IEkga25vdyB0aGF0IGl0ZXJhdGluZyBhIERPTU5vZGUncyBjaGlsZHJlbiB1
c2luZyBmaXJzdENoaWxkIGFuZA0KPiBuZXh0U2libGluZyBieQ0KPiByZWZl
cmVuY2UgY2F1c2VzIHRyb3VibGUsIHRoYW5rIHlvdS4gVGhlIHByb2JsZW0g
aXMgdGhhdCBpdCBjYXVzZXMNCj4gdHJvdWJsZQ0KPiB3aXRoIG9iamVjdHMg
dW5yZWxhdGVkIHRvIHRoZSBsb29wIGl0c2VsZiwgZS5nLiB0byB2YXJpYWJs
ZXMgZGVmaW5lZA0KPiBfYWZ0ZXJfDQo+IHRoZSBsb29wIGhhcyB0ZXJtaW5h
dGVkLg0KDQpJIGRvbid0IHRoaW5rIGl0J3MgcG9zc2libGUgdG8gYW5zd2Vy
IHRoaXMgZm9yIHN1cmUgd2l0aG91dCBzZWVpbmcgbW9yZSBvZiB0aGUgY29k
ZSAtLSBhdCBsZWFzdCB0aGUgY29tcGxldGUgYm9keSBvZiB0aGUgbG9vcCwg
cGx1cyBhcyBmYXIgYXMgYW55IGZ1cnRoZXIgdXNlIG9mIHRoZSB2YXJpYWJs
ZSAkY2hpbGQgKGFuZCBhbnkgb3RoZXIgdmFyaWFibGVzIGFzc2lnbmVkIGZy
b20gaXQpLg0KDQoNCkNoZWVycyENCg0KTWlrZQ0KIC0tIA0KTWlrZSBGb3Jk
LA0KRWxlY3Ryb25pYyBJbmZvcm1hdGlvbiBEZXZlbG9wZXIsIExpYnJhcmll
cyBhbmQgTGVhcm5pbmcgSW5ub3ZhdGlvbiwgIA0KTGVlZHMgTWV0cm9wb2xp
dGFuIFVuaXZlcnNpdHksIEM1MDcsIENpdmljIFF1YXJ0ZXIgQ2FtcHVzLCAN
Cldvb2Rob3VzZSBMYW5lLCBMRUVEUyzCoCBMUzEgM0hFLMKgIFVuaXRlZCBL
aW5nZG9tIA0KRW1haWw6IG0uZm9yZEBsZWVkc21ldC5hYy51ayANClRlbDog
KzQ0IDExMyA4MTIgNDczMA0KDQoNCgoKVG8gdmlldyB0aGUgdGVybXMgdW5k
ZXIgd2hpY2ggdGhpcyBlbWFpbCBpcyBkaXN0cmlidXRlZCwgcGxlYXNlIGdv
IHRvIGh0dHA6Ly9kaXNjbGFpbWVyLmxlZWRzbWV0LmFjLnVrL2VtYWlsLmh0
bQo=

Re: DOMNode children iteration (was Re: array() returns something weird)

am 26.08.2009 12:06:59 von webmaster

--Boundary-00=_DlQlKfmLuOIKA6f
Content-Type: Text/Plain;
charset="utf-8"
Content-Transfer-Encoding: 7bit

> I really can't see why you'd want to use references in the posted
> loop anyway -- it's not likely to gain you any performance, and, as
> I understand it, may actually run more slowly than the
> non-reference version.

The why is irrelevant. It is perfectly legal PHP, and while it might be
illegal usage of DOMNode, it should only break the DOMNode, and not PHP
execution environment.

> I don't think it's possible to answer this for sure without seeing more of
> the code -- at least the complete body of the loop, plus as far as any
> further use of the variable $child (and any other variables assigned from
> it).

OK, I modified the example to show the problem _very_ directly. I commented out
the recursion-tracing echos, and added this code in renderObject() below the
if() that chooses between the good and evil loop, which means that the added
code is always executed immediately after the loop:

$x=array();
$y="y";
$z=1;
var_dump($xy,$y,$z);
echo "\n";

Note that these variables:

- are first defined at this point
- are initialized immediately
- are initialized with immediate data (empty array and two scalars), not
with results of prior computation
- are never used or changed except for being dumped
- don't get any references to them created

Therefore one must expect that var_dump will always dump this:

array(0) {
}
string(1) "y"
int(1)

However it sometimes dumps this:

NULL
NULL
NULL

Best regards,
Szczepan Holyszewski

--Boundary-00=_DlQlKfmLuOIKA6f
Content-Type: application/x-php;
name="testme.php"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename="testme.php"


/*
This program demonstrates mayhem caused by iterating over a DOMNode's children
using firstChild and nextSibling TAKEN BY REFERENCE.

It instantiates a DOMDocument, loads an XML fragment into it and processes it
three times - the good way, the mixed way (read below) and the evil way. Each time
recursion progress is logged and (trivial) transformation result is dumped
(if not errored out earlier).

* First time it takes a path in renderObject() that iterates over
child nodes using a DOMNodeList obtained with a DOMXPath query.

* Second time it uses DOMNodeList at the outermost level in renderObject()
but firstChild/nextSibling by reference at inner levels. This
demonstrates very nice trashing of local variables from which
transformation result is assembled in renderObject().

* Third time it always uses firstChild/nextSibling in renderObject().
On my machine it errors out at the outermost level but AFTER returning
from recursion.
*/


define('GOOD_WAY', true);
define('EVIL_WAY', false);

//The XML is formatted so that objects only contain params
//and no text or whitespace in between

$xmlfragment = <<
Some text.

Some parameter text.
Some parameter text.

Some nested parameter text.
Some nested parameter text.

true

More nested parameter text
More nested parameter text


Some more text

XMLFRAGMENT;

$doc = new DOMDocument("1.0", "utf-8"); $doc->loadXML($xmlfragment);

$root = $doc->childNodes->item(0);

//uncomment to display errors
//ini_set("display_errors", "On");

echo "THE GOOD WAY (DOMNodeList):\n\n";
//echo "Recursion structure:\n\n";
$innerWay = GOOD_WAY;
$result=render($root, true);
echo "\nTransformation result:\n$result\n";
echo "Success!\n\n";

echo "THE MIXED WAY (DOMNodeList at outermost level, then firstChild/nextSibling by ref):\n\n";
//echo "Recursion structure:\n\n";
$innerWay = EVIL_WAY;
$result=render($root, true);
echo "\nTransformation result:\n$result\n";
echo "Is it really a success?\n\n";

echo "THE EVIL WAY (firstChild/nextSibling by ref):\n\n";
//echo "Recursion structure:\n\n";
$result=render($root, false);
echo "\nTransformation result:\n$result\n";
echo "Unexpected success!\n\n";

function render(&$node, $whichWay) {

$ret="";
//for each node
for($i=0; $i<$node->childNodes->length; ++$i) {

$child = $node->childNodes->item($i);

//if text node, append
if ($child instanceof DOMText) $ret .= $child->wholeText;

//if , render and append
else if ($child instanceof DOMElement && $child->tagName == "object") {

//echo '->renderObject()\n';
$ret .= renderObject($child, $whichWay);
//echo '<-';
}
}
return $ret;
}

function renderObject(&$node, $whichWay) {

$objectName = $node->getAttribute("name");
$objectType = $node->getAttribute("type");
$params = array();

if ($whichWay==GOOD_WAY) {

$xpath = new DOMXPath($node->ownerDocument);
$paramNodes = $xpath->evaluate("./param", $node);
for($i=0; $i<$paramNodes->length; ++$i) {

$paramNode = $paramNodes->item($i);
$paramName = $paramNode->getAttribute("name");
//echo "->render()\n";
$paramValue = render($paramNode, $GLOBALS['innerWay']); //which way to use at inner levels?
//echo "<-\n";
$params[$paramName] = $paramValue;
}
}

else { //($which_way == EVIL_WAY)

for($paramNode = &$node->firstChild; $paramNode; $paramNode = &$paramNode->nextSibling) {

$paramName = $paramNode->getAttribute("name");
//echo "->render()\n";
$paramValue = render($paramNode, false);
//echo "<-\n";
$params[$paramName]=$paramValue;
}
}

$x=array();
$y="y";
$z=1;
var_dump($x,$y,$z);
echo "\n";

//build some simple transformation result
$ret = "[object type='$objectType' name='$objectName']";
foreach($params as $n => $v) $ret.="[param name='$n']{$v}[/param]";
$ret.="[/object]";

return $ret;
}




--Boundary-00=_DlQlKfmLuOIKA6f
Content-Type: text/plain; charset=us-ascii

--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php
--Boundary-00=_DlQlKfmLuOIKA6f--